#ifndef SH_MD5_HPP
#define SH_MD5_HPP

#include <string>
#include <cstring>
#if defined(linux)
//linux下使用openssl，cmakelist需要link-lcrypto
#include <openssl/crypto.h>
#include <openssl/md5.h>
#endif


namespace sh
{
class Md5
{
public:
#if defined(linux)
    static std::string md5(const std::string &str)
    {
        MD5_CTX hashCtx;
        unsigned char hashRet[MD5_DIGEST_LENGTH];

        int ret = MD5_Init(&hashCtx);
        if (ret == 0)
        {
            return "";
        }

        ret = MD5_Update(&hashCtx, str.c_str(), str.size());
        if (ret == 0)
        {
            return "";
        }

        ret = MD5_Final(hashRet, &hashCtx);
        if (ret == 0)
        {
            return "";
        }

        OPENSSL_cleanse(&hashCtx, sizeof(hashCtx));

        std::string md5Text;
        char buf[2] = {'\0'};

        for (int i = 0; i < MD5_DIGEST_LENGTH * 2; ++i)
        {
            memset(buf, '\0', sizeof(buf));
            if (i & 0x1)
            {
                sprintf(buf, "%x", (hashRet[i / 2]) & 0xf);
            }
            else
            {
                sprintf(buf, "%x", (hashRet[i / 2] >> 4) & 0xf);
            }
            md5Text += buf;
        }

        return md5Text;
    }
#endif
};
}

#endif //SH_MD5_HPP
